#include "CCore.h"
#include "CVideoManager.h"
#include "CInputManager.h"
#include "CTimerManager.h"
#include "CSoundManager.h"
#include "CScene.h"
#include "CException.h"

std::auto_ptr<CCore> CCore::m_instance;

CCore::CCore()
{
    pr_Scene = NULL;
    bEnded   = false;
    bPaused	 = false;
}

CCore::~CCore()
{
    Release();
}

bool CCore::Release()
{
    if (pr_Scene){
        pr_Scene = NULL;
    }
    return true;
}

void CCore::Initialize()
{
    if (!CVideoManager::getInstance()->Initialize()){
        CException("[CCore::Initialize@65] Can't initialize Video System.").Raise();
        exit(-1);
    }

    if (!CInputManager::getInstance()->Initialize()){
        CException("[CCore::Initialize@65] Can't initialize Input System").Raise();
        exit(-1);
    }

    if (!CSoundManager::getInstance()->Initialize()){
        CException("[CCore::Initialize@65] Can't initialize Sound System").Raise();
        exit(-1);
    }

    if (!pr_Scene)
        SetCurrentScene(0);
}

bool CCore::Ended()
{
    if (bEnded)
        Release();
    return bEnded;
}

void CCore::Run()
{
    while(!bEnded){
        CInputManager::getInstance()->Read();
        CTimerManager::getInstance()->Update();

        if(CInputManager::getInstance()->KeyPressed(SDLK_ESCAPE))
            bEnded = true;

        if(CInputManager::getInstance()->EventType(SDL_QUIT))
            bEnded = true;

        if (pr_Scene){
            pr_Scene->Draw();
            if (!bPaused){
                pr_Scene->Update();
                pr_Scene->Execute();
            }
        }

        CVideoManager::getInstance()->Blit();
        CVideoManager::getInstance()->ClearScreen();
    }
}

void CCore::AddScene(CScene *pr_NewScene)
{
    if (pr_NewScene){
        Scenes.push_back(pr_NewScene);
    }
}

void CCore::SetCurrentScene(int iIndex)
{
    if (iIndex < (int)Scenes.size()){
        CScene *pr_NewScene = Scenes[iIndex];
        if (pr_NewScene){
            if (pr_Scene){
                pr_Scene->Release();
                pr_Scene = NULL;
            }

            pr_Scene = pr_NewScene;

            if (!pr_Scene->Initialize()){
                pr_Scene->Release();
                pr_Scene = NULL;
            }

            CTimerManager::getInstance()->Reset();
        }
    }
}

void CCore::Pause()
{
    bPaused = true;
}

void CCore::Resume()
{
    if (bPaused){
        CTimerManager::getInstance()->Reset();
        bPaused = false;
    }
}
